package com.leijie.nio;

import io.netty.util.CharsetUtil;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.*;

/**
 * @author LeiJie
 * @time 2020-5-12 14:57
 * @desc Nio网络编程
 */
public class NioServer {

    private static Map<String,SocketChannel> clientMap = new HashMap();

    public static void main(String[] args) throws Exception{
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.configureBlocking(false);
        SocketAddress socketAddress = new InetSocketAddress(8899);
        serverSocketChannel.bind(socketAddress);

        //打开一个selector
        Selector selector = Selector.open();
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        System.out.println("服务端口[8899]已启动...");
        while (true){
            //selector阻塞
            selector.select();

            Iterator<SelectionKey> selectionKeys = selector.selectedKeys().iterator();
            while (selectionKeys.hasNext()){
                SelectionKey selectionKey = selectionKeys.next();
                SocketChannel client = null;
                try {
                    System.out.println("selectionKeyIsvalid:"+selectionKey.isValid());
                    if (!selectionKey.isValid()){
                        continue;
                    }
                    if (selectionKey.isAcceptable()){
                        ServerSocketChannel serverSocketChannel1 = (ServerSocketChannel) selectionKey.channel();
                        client = serverSocketChannel1.accept();
                        client.configureBlocking(false);
                        client.register(selector,SelectionKey.OP_READ);
                        String key = "【"+ UUID.randomUUID().toString()+"】";
                        clientMap.put(key,client);
                    }else if (selectionKey.isReadable()){
                        client = (SocketChannel) selectionKey.channel();
                        ByteBuffer readBuffer = ByteBuffer.allocate(512);
                        int count = client.read(readBuffer);
                        if (count > 0){
                            readBuffer.flip();
                            String message = String.valueOf(CharsetUtil.UTF_8.decode(readBuffer).array());
                            System.out.println(client + ":" + message);

                            String sendKey = null;
                            for (Map.Entry<String, SocketChannel> en : clientMap.entrySet()) {
                                if (client == clientMap.get(en.getKey())){
                                    sendKey = en.getKey();
                                    break;
                                }
                            }
                            for (Map.Entry<String, SocketChannel> entry : clientMap.entrySet()) {
                                ByteBuffer buffer = ByteBuffer.allocate(1024);
                                buffer.put((sendKey+"[:]"+message).getBytes());
                                buffer.flip();
                                entry.getValue().write(buffer);
                            }
                        }else{
                            client.close();
                            System.out.println("客户端关闭，readCount:"+count);
                        }
                    }
                } catch (IOException e) {
                    client.close();
                    e.printStackTrace();
                }
                selectionKeys.remove();
            }
        }
    }

}
